package com.gujia.concurrency.example.aqs;

import com.gujia.concurrency.annoations.ThreadSafe;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 闭锁：CountDownLatch
 * 是一个同步辅助类，通过它可以完成类似于阻塞当前线程的功能，即：一个线程或多个线程一直等待，
 * 直到其他线程执行操作完成。CountDownLatch用了一个给定的计数器进行初始化。
 * 该计数器的操作是原子操作，就是同时只能有一个线程去操作该计数器。调用该类的await()方法会一直处于阻塞状态，
 * 直到其他线程调用countDown()方法,使当前计数器的值变成零。
 * 每次调用countDown()的时候计数器的值会减一。当计数器的值减到零的时候所有因调用await()方法，处于阻塞状态的线程。
 * 就会继续往下执行，这种操作只会出现一次，因为这种计数器是不能被重置的。
 *
 */
public class CountDownLatchExample1 {

    private  static int threadCount = 200;
    public static void main(String[] args) {

        ExecutorService executorService = Executors.newCachedThreadPool();

        final CountDownLatch countDownLatch = new CountDownLatch(threadCount);

        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        test(threadNum);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        countDownLatch.countDown();
                    }
                }
            });
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("main finished !");
        executorService.shutdown();
    }


    private static void test(int threadNum) throws Exception{
        Thread.sleep(100);
        System.out.println("ThreadNum -> "+threadNum);
        Thread.sleep(100);
    }
}
